
-- This is the template for the testbench for Lab 3.  You should start
-- with this, it will make your life easier.  Before starting on this 
-- lab, make sure you review your notes from the tutorial and read the
-- entire handout carefully.
--
--
-- @Modified by: Phuong Tran		#54355102
--				 Krzysztof Mazurek	#72329097
--				 
--	@Lab Section: L2C				
--
-- @Date:		 07/02/2012

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library work;
use work.all;

entity datapath_testbench is
end datapath_testbench ;

architecture behavioural of datapath_testbench is

    component datapath is
	     port(
   	    datapath_in : in std_logic_vector(7 downto 0);
		    mux1sel : in std_logic;
		    write : in std_logic;
		    writenum : in std_logic_vector(2 downto 0);
		    readnum : in std_logic_vector(2 downto 0);
		    loada : in std_logic;
		    loadb : in std_logic;
		    mux2sel : in std_logic;
		    funct : in std_logic_vector(1 downto 0);
		    loadc : in std_logic;
		    clk : in std_logic;
		    datapath_out : out std_logic_vector(7 downto 0));
    end component;

-- Some internal signals to the datapath.  I have assigned initial values
-- here, just to show you that you can do it.  
	 
signal datapath_in : std_logic_vector(7 downto 0) := "00000000";
signal mux1sel : std_logic := '0';
signal write : std_logic := '0';
signal writenum : std_logic_vector(2 downto 0) := "000";
signal readnum : std_logic_vector(2 downto 0) := "000";
signal loada : std_logic := '0';
signal loadb : std_logic := '0';
signal mux2sel : std_logic := '0';
signal funct : std_logic_vector(1 downto 0) := "00";
signal loadc : std_logic := '0';
signal clk : std_logic := '0';
signal datapath_out : std_logic_vector(7 downto 0) := "00000000";

constant PERIOD :time := 10 ns;

begin  
	 u0: datapath
		 port map( 
	    datapath_in => datapath_in,
			mux1sel => mux1sel,
			write => write,
			writenum => writenum,
			readnum => readnum,
			loada => loada,
			loadb => loadb,
			mux2sel => mux2sel,
			funct => funct,
			loadc => loadc,
			clk => clk,
			datapath_out => datapath_out);		

  -- Process to generate clock pattern
  
  clk_gen : process
	begin
	   clk <= '0';
 		 wait for PERIOD/2;
 		 clk <= '1';
 		 wait for PERIOD/2;
	end process;
	
	stimulus : process
	begin
	 
	   wait until clk='0' and clk'event;
  
     -- send the input pattern that will cause the number 3 to 
     -- be stored in register R2.  Note this will take only
     -- one cycle.

     datapath_in <= "00000011"; -- binary for 3
     mux1sel <= '1';  -- select right-hand path through top mux
     write <= '1';  -- write to register file during this cycle
     writenum <= "010"; -- binary for 2
     readnum <= "000"; -- doesn't matter for this cycle
     loada <= '0';  -- do not update reg a this cycle
     loadb <= '0';  -- do not update reg b this cycle
     mux2sel <= '0'; -- does not matter for this cycle
     funct <= "00";  -- does not matter for this cycle
     loadc <= '0';   -- do not update reg c during this cycle
	   wait until clk='0' and clk'event;
 
     -- send the input pattern that will cause the number 5 to 
     -- be stored in register R3.  Note this will take only
     -- one cycle

	  -- write some code here to describe the input patterns for this cycle

     datapath_in <= "00000101"; -- binary for 5
     mux1sel <= '1';  -- select right-hand path through top mux
     write <= '1';  -- write to register file during this cycle
     writenum <= "011"; -- binary for 3
     readnum <= "000"; -- doesn't matter for this cycle
     loada <= '0';  -- do not update reg a this cycle
     loadb <= '0';  -- do not update reg b this cycle
     mux2sel <= '0'; -- does not matter for this cycle
     funct <= "00";  -- does not matter for this cycle
     loadc <= '0';   -- do not update reg c during this cycle	  
	  wait until clk='0' and clk'event;
    	            
     -- send the input pattern that will cause the value in 
     -- register R3 to be copied to register R4.  Note, as discussed
     -- in the tutorial, this will take three cycles.  

     -- Write some code here to describe what happens on the first cycle
     -- FIRST CYCLE: READ R3 INTO REGISTER A
     
     datapath_in <= "00000000"; 
     mux1sel <= '0'; 
     write <= '0';  
     writenum <= "000"; 
     readnum <= "011"; 
     loada <= '1';  
     loadb <= '0';  
     mux2sel <= '0'; 
     funct <= "00";  
     loadc <= '0';   
 
	  wait until clk='0' and clk'event;
     -- Write some code here to describe what happens on the second cycle
     -- SECOND CYCLE: MULTIPLY BY 1 AND LATCHED RESULT INTO REGISTER C
     datapath_in <= "00000000"; 
     mux1sel <= '0'; 
     write <= '0';  
     writenum <= "000"; 
     readnum <= "000"; 
     loada <= '0';  
     loadb <= '0'; 
     mux2sel <= '1'; 
     funct <= "01";  
     loadc <= '1';   

	  wait until clk='0' and clk'event;
	  -- Write some code here to describe what happens on the third cycle
	  -- THIRD CYCLE: WRITE DATAOUT INTO R4
     datapath_in <= "00000000"; 
     mux1sel <= '0';  
     write <= '1'; 
     writenum <= "100"; 
     readnum <= "000"; 
     loada <= '0';  
     loadb <= '0';  
     mux2sel <= '0';
     funct <= "00";  
     loadc <= '0';  

	  wait until clk='0' and clk'event;
      
     -- send the input pattern that will add the value in R2 
     -- to the value in R4 and store the result in R5.  This will
     -- require 4 cycles, as discussed in the tutorial

     -- Write some code here to describe what happens on the first cycle
     -- FIRST CYCLE: READ R2 INTO REGISTER A
     
     datapath_in <= "00000000"; 
     mux1sel <= '0';  
     write <= '0';  
     writenum <= "000"; 
     readnum <= "010"; 
     loada <= '1'; 
     loadb <= '0';  
     mux2sel <= '0'; 
     funct <= "00";  
     loadc <= '0';   
	  wait until clk='0' and clk'event;
     -- Write some code here to describe what happens on the second cycle
     -- SECOND CYCLE: READ R4 INTO REGISTER B
     
     datapath_in <= "00000000"; 
     mux1sel <= '0';  
     write <= '0';  
     writenum <= "000"; 
     readnum <= "100"; 
     loada <= '0';  
     loadb <= '1';  
     mux2sel <= '0'; 
     funct <= "00";  
     loadc <= '0';   
	  wait until clk='0' and clk'event;
	  -- Write some code here to describe what happens on the third cycle
     -- THIRD CYCLE: ADD AND LATCH VALUE INTO REGISTER C
     
     datapath_in <= "00000000"; 
     mux1sel <= '0';  
     write <= '0'; 
     writenum <= "000"; 
     readnum <= "000"; 
     loada <= '0';  
     loadb <= '0';  
     mux2sel <= '0'; 
     funct <= "10";
     loadc <= '1';   
	  wait until clk='0' and clk'event;
	  -- Write some code here to describe what happens on the fourth cycle
	  -- 4 CYCLE: WRITE DATAOUT INTO R5
     datapath_in <= "00000000"; 
     mux1sel <= '0'; 
     write <= '1';  
     writenum <= "101"; 
     readnum <= "000"; 
     loada <= '0';  
     loadb <= '0';  
     mux2sel <= '0'; 
     funct <= "00";  
     loadc <= '0';   
	  wait until clk='0' and clk'event;     
	   
	   -- wait forever at the end of the simulation
	   
	  wait;
	end process;   

end behavioural;